﻿#pragma once

#include <iostream>
#include <thread>
#include <mutex>
#include <list>
#include <QString>
#include <QDebug>

struct AVPacket;
struct AVFrame;
struct AVCodecParameters;
struct AVRational;

/// <summary>
/// ffmpeg编解码工具集文件
/// </summary>
/// 
//日志级别 DEBUG INFO ERROR FATAL
enum XLogLevel
{
	YLOG_TYPE_DEBUG,
	YLOG_TYPE_INFO,
	YLOG_TPYE_ERROR,
	YLOG_TYPE_FATAL
};
#define LOG_MIN_LEVEL YLOG_TYPE_DEBUG
#define YLOG(s,level) \
    if(level>=LOG_MIN_LEVEL) { \
       qDebug()<<QString::number(level) << "[" << __FILE__ << ":" << __LINE__ << "]" << QString::fromStdString(s); \
    }
#define LOGDEBUG(s) YLOG(s,YLOG_TYPE_DEBUG)
#define LOGINFO(s) YLOG(s,YLOG_TYPE_INFO)
#define LOGERROR(s) YLOG(s,YLOG_TPYE_ERROR)
#define LOGFATAL(s) YLOG(s,YLOG_TYPE_FATAL)

//线程暂停多久，单位是毫秒
void MSleep(unsigned int ms);

//获取当前时间戳 毫秒
long long NowMs();

//手动销毁AVFrame
void YFreeFrame(AVFrame** frame);

long long YRescale(long long pts,
	AVRational* src_time_base,
	AVRational* des_time_base);


class YThread
{
public:
	/// <summary>
	/// 启动线程
	/// </summary>
	virtual void Start();

	//设置线程退出标志
	virtual void Exit();

	/// <summary>
	/// 停止线程，设置退出标志等待线程退出
	/// </summary>
	virtual void Stop();

	//等待线程退出
	virtual void Wait();

	/// 以下是责任链不部分
	//执行责任链任务，需要 进行重载
	virtual void Do(AVPacket* pkt) {};

	//传递任务到下一个责任链函数
	virtual void Next(AVPacket* pkt)
	{
		std::unique_lock<std::mutex> lock(mut_);
		if (next_)
		{
			next_->Do(pkt);
		}
	}

	//设置责任链下一个节点
	void setNext(YThread* yt)
	{
		std::unique_lock<std::mutex> lock(mut_);
		next_ = yt;
	}

	//暂停或者播放
	virtual void Pause(bool is_pause) { is_pause_ = is_pause; };

	bool isPause() { return is_pause_; }

protected:
	/// <summary>
	/// 线程执行的入口函数，纯虚方法，子类必须要进行实现
	/// </summary>
	virtual void Working() = 0;

	//线程退出标志
	bool isExit_ = false;

	//线程索引号
	int index_ = 0;

	//是否暂停标志
	bool is_pause_ = false;


private:
	std::thread th_;//线程对象
	std::mutex mut_;//线程锁对象
	YThread* next_ = nullptr;//责任链下一个节点

};


/// <summary>
/// 音视频参数类，用于临时存储音视频参数
/// </summary>
class YAVParameters {
public:
	AVCodecParameters* para = nullptr;  //音视频参数
	AVRational* time_base = nullptr;    //时间基数
	long long total_ms = 0;             //总时长 毫秒

	//创建对象
	static YAVParameters* Create();
	~YAVParameters();
private:
	//禁止外部创建对象
	YAVParameters();
};


/// <summary>
/// 线程安全avpacket list
/// </summary>
class YAVPacketList
{
public:
	AVPacket* Pop();
	void Push(AVPacket* pkt);
	int Size();
	void Clear();
private:
	std::list<AVPacket*> pkts_;
	int max_packets_ = 1000;//最大列表数量，超出清理
	std::mutex mux_;
};


class YAVFrameList
{
public:
	AVFrame* Pop();
	void Push(AVFrame* frame);
	int Size();
	void Clear();
private:
	std::list<AVFrame*> frames_;
	int max_frames_ = 60;//最大列表数量，超出清理
	std::mutex mux_;
};

